﻿namespace SimpleWebServices
{
    using System;
    using System.Globalization;
    using System.Threading;
    using Xunit;

    public sealed class UriExtensionMethodsFacts
    {
        [Fact]
        public void typedef()
        {
            Assert.True(typeof(UriExtensionMethods).IsStatic());
        }

        [Fact]
        public void op_ToContentLocation_Uri_string()
        {
            CultureInfo culture = Thread.CurrentThread.CurrentUICulture;

            try
            {
                Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr");

                Uri expected = new Uri("http://example.com/test?a=b");
                Uri actual = new Uri("http://example.com/test.fr.html?a=b").ToContentLocation(".html");

                Assert.Equal<Uri>(expected, actual);
            }
            finally
            {
                Thread.CurrentThread.CurrentUICulture = culture;
            }
        }

        [Fact]
        public void op_ToContentLocation_UriRelative_string()
        {
            Assert.Throws<ArgumentOutOfRangeException>(() => (new Uri("/", UriKind.Relative)).ToContentLocation(".html"));
        }

        [Fact]
        public void op_ToContentLocation_Uri_stringEmpty()
        {
            Assert.Throws<ArgumentOutOfRangeException>(() => new Uri("http://example.com/").ToContentLocation(string.Empty));
        }

        [Fact]
        public void op_ToContentLocation_Uri_stringNull()
        {
            Assert.Throws<ArgumentNullException>(() => new Uri("http://example.com/").ToContentLocation(null));
        }

        [Fact]
        public void op_ToContentLocation_Uri_CultureInfo_string()
        {
            Uri expected = new Uri("http://example.com/test?a=b");
            Uri actual = new Uri("http://example.com/test.fr.html?a=b").ToContentLocation(new CultureInfo("fr"), ".html");

            Assert.Equal<Uri>(expected, actual);
        }

        [Fact]
        public void op_ToContentLocation_UriNull_CultureInfo_string()
        {
            Assert.Throws<ArgumentNullException>(() => (null as Uri).ToContentLocation(new CultureInfo("fr"), ".html"));
        }

        [Fact]
        public void op_ToContentLocation_UriRelative_CultureInfo_string()
        {
            Assert.Throws<ArgumentOutOfRangeException>(() => (new Uri("/", UriKind.Relative)).ToContentLocation(new CultureInfo("fr"), ".html"));
        }

        [Fact]
        public void op_ToContentLocation_Uri_CultureInfoInvariantCulture_string()
        {
            Assert.Throws<ArgumentOutOfRangeException>(() => new Uri("http://example.com/").ToContentLocation(CultureInfo.InvariantCulture, ".html"));
        }

        [Fact]
        public void op_ToContentLocation_Uri_CultureInfoNull_string()
        {
            Assert.Throws<ArgumentNullException>(() => new Uri("http://example.com/").ToContentLocation(null, ".html"));
        }

        [Fact]
        public void op_ToContentLocation_Uri_CultureInfo_stringEmpty()
        {
            Assert.Throws<ArgumentOutOfRangeException>(() => new Uri("http://example.com/").ToContentLocation(new CultureInfo("fr"), string.Empty));
        }

        [Fact]
        public void op_ToContentLocation_Uri_CultureInfo_stringNull()
        {
            Assert.Throws<ArgumentNullException>(() => new Uri("http://example.com/").ToContentLocation(new CultureInfo("fr"), null));
        }

        [Fact]
        public void op_ToUri_Uri_string()
        {
            Uri expected = new Uri("http://example.com/test");
            Uri actual = new Uri("http://example.com").ToUri("test");

            Assert.Equal<Uri>(expected, actual);
        }

        [Fact]
        public void op_ToUri_Uri_stringEmpty()
        {
            Uri expected = new Uri("http://example.com/");
            Uri actual = expected.ToUri(string.Empty);

            Assert.Equal<Uri>(expected, actual);
        }

        [Fact]
        public void op_ToUri_Uri_stringNull()
        {
            Assert.Throws<ArgumentNullException>(() => new Uri("http://example.com/").ToUri(null as string));
        }

        [Fact]
        public void op_ToUri_UriNull_string()
        {
            Assert.Throws<ArgumentNullException>(() => (null as Uri).ToUri("/"));
        }

        [Fact]
        public void op_ToUri_UriRelative_string()
        {
            Assert.Throws<ArgumentOutOfRangeException>(() => new Uri("/", UriKind.Relative).ToUri("/"));
        }

        [Fact]
        public void op_ToUri_Uri_Uri()
        {
            Uri expected = new Uri("http://example.com/test");
            Uri actual = new Uri("http://example.com").ToUri(new Uri("test", UriKind.Relative));

            Assert.Equal<Uri>(expected, actual);
        }

        [Fact]
        public void op_ToUri_Uri_UriAbsolute()
        {
            Assert.Throws<ArgumentOutOfRangeException>(() => new Uri("http://example.com").ToUri(new Uri("http://example.org/test")));
        }

        [Fact]
        public void op_ToUri_Uri_UriNull()
        {
            Assert.Throws<ArgumentNullException>(() => new Uri("http://example.com").ToUri(null as Uri));
        }
    }
}